# Copyright 2018- The Pixie Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0

load("//bazel:pl_build_system.bzl", "pl_cc_library", "pl_cc_musl_binary", "pl_cc_test")

package(default_visibility = ["//src/stirling:__subpackages__"])

agent_files = [
    "Makefile.inner",
    "agent.c",
    "raw_symbol_update.h",
]

# This is the header file where we will put the version hash
# of the Pixie Java symbolization JVMTI source files.
# The hash itself will replace the "{}" below.
_hash_dot_h_fmt = [
    "#pragma once",
    "#define PX_JVMTI_AGENT_HASH \"{}\"",
]

hash_dot_h_fmt = "\n".join(_hash_dot_h_fmt)

# These are the commands we use inside of the genrule to write agent_hash.h.
# $(SRCS) is the list of JVMTI source files, which the genrule picks up from agent_files.
# xargs is used to write the hash value in place of the "{}" inside hash_dot_h_fmt.
hash_cmds = [
    "cat $(SRCS)",
    "sha256sum",
    "head -c 32",
    "xargs -I{} echo '" + hash_dot_h_fmt + "'",
]

hash_cmd = " | ".join(hash_cmds)

# This writes the file "agent_hash.h".
genrule(
    name = "agent_hash",
    srcs = agent_files,
    outs = ["agent_hash.h"],
    cmd = hash_cmd + " > $@",
)

pl_cc_library(
    # This is a "header only" pl_cc_library: agent.cc is used to create a .so that will be injected
    # to a target Java process.
    name = "cc_headers",
    hdrs = glob(["*.h"]) + ["agent_hash.h"],
)

# If we don't statically link libc, then the .so file will fail to be loaded on systems with older libc versions than we built with.
# glibc is a pain to link statically, so instead we link musl libc statically.
pl_cc_musl_binary(
    name = "px-java-agent",
    srcs = [
        "agent.c",
        "agent_hash.h",
        "raw_symbol_update.h",
    ],
    features = ["fully_static_link"],
    linkshared = True,
    deps = ["@com_oracle_openjdk_18//:jdk_includes"],
)

filegroup(
    name = "agent",
    srcs = ["px-java-agent"],
    visibility = [
        # Add visibility at top-level so that we can include
        # the lib in the pem image.
        "//:__pkg__",
        "//src/stirling:__subpackages__",
    ],
)

pl_cc_test(
    name = "agent_test",
    srcs = [
        "agent_hash.h",
        "agent_test.cc",
    ],
    data = [
        ":agent",
        "//src/stirling/source_connectors/perf_profiler/testing/java:profiler_test_with_agent",
    ],
    tags = [
        "no_asan",
    ],
    deps = [
        ":cc_headers",
        "//src/common/exec:cc_library",
        "//src/common/fs:cc_library",
        "//src/stirling/testing:cc_library",
    ],
)
